<template>
  <div class="project-plan">
    <a-spin tip="加载中..." :spinning="ganttInfo.spinning" style="height: 100%">
      <!-- 顶部任务栏 -->
      <div class="component-topbar">
        <div class="component-topbar__top flex-between">
          <div class="component-topbar__top-left">项目计划 - 全部计划</div>
          <template v-if="barControl.ganttManBarShow">
            <div class="component-topbar__top-right">
              <a-button type="primary" @click.stop="onbarAddTask"><plus-outlined />新建任务</a-button>
              <a-button type="primary" @click.stop="onbarEditTask"><edit-outlined />修改任务</a-button>
              <a-button type="primary" @click.stop="onbarExecTask"><login-outlined />执行任务</a-button>
              <a-button type="primary" @click.stop="onbarRemoveTask"><delete-outlined />删除任务</a-button>
            </div>
          </template>
        </div>
        <div class="component-topbar__bottom flex-between">
          <div class="tabs-view">
            <a-tabs v-model:activeKey="ganttInfo.tabsValue" @change="onTabsChange">
              <a-tab-pane v-for="v in ganttInfo.tabsList" :key="v.value" :tab="v.label"></a-tab-pane>
            </a-tabs>
          </div>
          <div class="gantt-bar">
            <template v-if="barControl.ganttSubBarShow">
              <!-- 甘特图任务表格，子分支显示和隐藏配置 -->
              <template v-if="barControl.branchTaskShow">
                <a-button v-if="!ganttInfo.taskSliderFlag" size="small" @click.stop="setTaskSlider">打开所有任务分支</a-button>
                <a-button v-else size="small" @click.stop="setTaskSlider">关闭所有任务分支</a-button>
              </template>

              <!-- 甘特图依赖线配置 -->
              <template v-if="barControl.showLinks">
                <a-button v-if="ganttInfo.showLinks" size="small" @click.stop="setLinks"> 关闭依赖线 </a-button>
                <a-button v-else size="small" @click.stop="setLinks"> 打开依赖线 </a-button>
              </template>

              <!-- 甘特图导出配置 -->
              <template v-if="barControl.exportModule">
                <a-button size="small" @click.stop="exportPDF">导出到PDF</a-button>
                <a-button size="small" @click.stop="exportPNG">导出到PNG</a-button>
              </template>

              <!-- 全屏配置模式 -->
              <template v-if="barControl.fullScreen">
                <a-button v-if="ganttInfo.fullScreen" size="small" @click.stop="onfullScreen">退出全屏 </a-button>
                <a-button v-else size="small" @click.stop="onfullScreen"> 全屏 </a-button>
              </template>

              <!-- 甘特图日期视图切换 -->
              <template v-if="barControl.dayview">
                <a-select ref="select" v-model:value="ganttInfo.curDayType" size="small" style="width: 70px" class="gantt-day-select" @change="onDayHandleChange">
                  <a-select-option v-for="v in ganttInfo.dayselectList" :key="v.value" :value="v.value">{{ v.label }}</a-select-option>
                </a-select>
              </template>
            </template>

            <a-select ref="select" v-model:value="ganttInfo.layoutConfigValue" size="small" style="width: 170px" class="gantt-day-select" @change="onLayoutHandleChange">
              <a-select-option v-for="v in ganttInfo.ganttLayoutList" :key="v.value" :value="v.value">{{ v.label }}</a-select-option>
            </a-select>
          </div>
        </div>
      </div>
      <!-- 甘特图主题区域 -->
      <div class="dhtmlx-gantt-view">
        <!-- <div class="slider-gantt-view">
        <left-circle-outlined />
        <right-circle-outlined />
      </div> -->
        <!-- 甘特图操作栏 -->
        <template v-if="grid.ganttViewInnerShow">
          <div class="ganntt-bar-view">
            <a-tooltip title="日期单位" color="#666">
              <a-select ref="select" v-model:value="ganttInfo.curDayType" style="width: 70px" class="gantt-day-select" size="small" @change="onDayHandleChange">
                <a-select-option v-for="v in ganttInfo.dayselectList" :key="v.value" :value="v.value">{{ v.label }}</a-select-option>
              </a-select>
            </a-tooltip>
            <a-tooltip v-if="ganttInfo.fullScreen" title="退出全屏" color="#666">
              <fullscreen-outlined style="margin: 0 10px" @click.stop="onfullScreen" />
            </a-tooltip>
            <a-tooltip v-else title="进入全屏" color="#666">
              <fullscreen-exit-outlined style="margin: 0 10px" @click.stop="onfullScreen" />
            </a-tooltip>
          </div>
        </template>
        <div ref="ganttRef" style="height: 100%" class="dhtmlx-gantt-view-layout"></div>

        <!-- 自定义甘特图表格 列字段 -->
        <div v-if="grid.showSetColumn" class="set-colunm-view" :style="{ left: ganttInfo.layoutConfigValue === 'grid' ? '96%' : '410px' }" @click.stop="onSetGanttColumn"><SettingOutlined /></div>
      </div>
    </a-spin>
  </div>
</template>
<script setup lang="ts">
import { gantt } from "dhtmlx-gantt"
import Dayjs from "dayjs"
import "dhtmlx-gantt/codebase/dhtmlxgantt.css"
import screenfull from "screenfull"
import { message } from "ant-design-vue"
import "@/plugins/ganttApi.js"

//每条任务数据格式
interface TaskItem {
  id: string | number //任务id
  text: string //任务名称
  start_date: string //开始日期
  end_date: string //结束日期
  progress: number //进度  0 ~ 1
  person: string //负责人
  status: number //状态
  //  前端依据status和parent处理，无需后台返回
  color: string //进度条颜色， 手动设置 {  父任务：#ebeef5。 子任务 => 已完成：#52c41a，进行中：1890ff，已延期： #ff4d4f}
  parent?: string | number //父任务id,是子任务必须有该熟悉
  [propName: string]: any
}

//每条任务依赖线数据格式
interface LinkItem {
  id: string | number
  source: string | number
  target: string | number
  type?: number
  [propName: string]: any
}

//任务状态每个item数据格式
interface stateItem {
  label: string
  key: string
  value: string
}

//甘特图整体数据格式
interface GanttData {
  fullScreen: boolean //全屏控制
  showLinks: boolean //任务依赖线控制
  taskSliderFlag: boolean //日期单位下拉框
  //日期单位下拉框
  curDayType: string
  dayselectList: { label: string; value: string }[]
  //任务状态切换
  tabsValue: string
  tabsList: stateItem[]
  task: TaskItem[] //任务列表
  links: LinkItem[] //任务依赖线列表
  selectionTask: (string | number)[] //被选中任务集合id
  spinning: boolean //loading标识
  ganttLayoutList: { label: string; value: string }[]
  layoutConfigValue: string //布局默认值
}

const props = defineProps({
  //甘特图功能
  barControl: {
    type: Object,
    default: () => ({
      ganttManBarShow: true,
      ganttSubBarShow: true, //甘特图操作栏
      exportModule: true, //导入导出功能
      branchTaskShow: true, //显示、隐藏子任务
      fullScreen: true, //设置全屏和非全屏
      showLinks: true, //显示、隐藏任务连线
      dayview: true, //甘特图日期视图切换
    }),
  },
  //操作列配置
  grid: {
    type: Object,
    default: () => ({
      ganttViewInnerShow: false,
      showActionColumn: false,
      showSetColumn: false,
      showCheckColumn: false,
      columns: [],
    }),
  },
  //@1 甘特图里面的task数据格式, 服务端直接返回 task， links
  ganttData: {
    type: Object,
    default: () => ({
      task: [],
      links: [],
    }),
  },

  //默认按日维度展示
  ganttViewDefault: {
    type: String,
    default: "day",
  },

  //项目开始和结束日期
  projectDate: {
    type: Object,
    default: () => ({
      start_date: "",
      end_date: "",
    }),
  },
})

watch(
  //父组件传递的数据发送改变触发，进行初始化甘特图
  () => props.ganttData,
  curTaskAry => {
    nextTick(() => {
      ganttInfo.task = curTaskAry.task
      ganttInfo.links = curTaskAry.links
      initGantt()
    })
  },
  {
    deep: true,
  },
)

//甘特图相关数据
const ganttRef = ref()
const ganttInfo = shallowReactive<GanttData>({
  spinning: true,
  fullScreen: false,
  showLinks: true,
  taskSliderFlag: true,
  curDayType: props.ganttViewDefault,
  dayselectList: [
    { label: "小时", value: "hour" },
    { label: "天", value: "day" },
    { label: "周", value: "week" },
    { label: "月", value: "month" },
    { label: "季度", value: "quarter" },
    { label: "年", value: "year" },
  ],
  tabsValue: "-1",
  tabsList: [
    { label: "全部", value: "-1", key: "-1" },
    { label: "未开始", value: "0", key: "0" },
    { label: "进行中", value: "1", key: "1" },
    { label: "已完成", value: "2", key: "2" },
    { label: "已通过", value: "5", key: "5" },
    { label: "已驳回", value: "3", key: "3" },
  ],
  ganttLayoutList: [
    { label: "全部", value: "gridAndTimeLine" },
    { label: "仅工单列表", value: "grid" },
    { label: "仅甘特图", value: "timeLine" },
  ],
  layoutConfigValue: "gridAndTimeLine",
  task: [],
  links: [],
  selectionTask: [],
})

//定义表格列需要插入的复选框，选择进行处理任务
const checkboxColumnTemplate = (task: TaskItem) => {
  return `<input id='ch1${task.id}' type='checkbox' onclick='onGanttCheckTask(this,${task.id})'></input>`
}

//操作列
const actionColumnTemplate = (task: TaskItem) => {
  return `
    <p>
      <span class='action-item' onclick=onGanttAddTask(${task.id})>新增</span>
      <span class='action-item' onclick=onGanttRemoveTask(${task.id})>删除</span>
      <span class='action-item' onclick=onGanttExecTask(${task.id})>执行</span>
      <span class='action-item' onclick=onGanttEditTask(${task.id})>修改</span>
    </p>
  `
}

//甘特图配置
const gannttConfig = {
  //设置语言,使用中文
  lang: "cn",

  //甘特图图表宽度自适应
  autofit: true,

  //关闭所有错误提示信息：gantt有自己的异常消息，如果不关闭可能页面会弹出异常消息
  show_errors: false,

  //布局，左右滚轮都独立
  layout: {
    css: "gantt_container",
    cols: [
      {
        width: 450,
        min_width: 450,
        rows: [
          {
            view: "grid",
            scrollX: "gridScroll",
            scrollable: true,
            scrollY: "scrollVer",
          },
          { view: "scrollbar", id: "gridScroll", group: "horizontal" },
        ],
      },
      { resizer: true, width: 1 },
      {
        rows: [
          { view: "timeline", scrollX: "scrollHor", scrollY: "scrollVer" },
          { view: "scrollbar", id: "scrollHor", group: "horizontal" },
        ],
      },
      { view: "scrollbar", id: "scrollVer" },
    ],
  },
  //只读模式（用此模式就不能对图形进行编辑）
  readonly: false,

  //是否显示左侧表格
  show_grid: true,

  //图表刷新后，滚动条的位置跟原来保持一致
  preserve_scroll: true,
  round_dnd_dates: true,

  reorder_grid_columns: true,

  //是否开启task任务多选
  multiselect: false,

  //点击表头可排序
  sort: false,
  //允许表格行拖放
  drag_project: true,
  //左侧表格列配置
  columns: [
    // {
    //   name: "wbs",
    //   label: "序号",
    //   width: 60,
    //   align: "center",
    //   template: gantt.getWBSCode,
    // },
    // { name: "buttons", label: "选择", width: 80, template: checkboxColumnTemplate, align: "center" },
    // {
    //   name: "text",
    //   label: "任务标题",
    //   width: 180,
    //   tree: true,
    //   align: "center",
    // },
    // {
    //   name: "progress",
    //   label: "进度",
    //   width: 90,
    //   align: "center",
    //   template: (obj: TaskItem) => {
    //     return `${obj.progress * 100}%`
    //   },
    // },
    // {
    //   name: "status",
    //   label: "状态",
    //   width: "90",
    //   align: "center",
    //   template: (obj: TaskItem) => {
    //     //动态处理
    //     return `${statusObj[obj.status]}`
    //   },
    // },
    // {
    //   name: "person",
    //   label: "负责人",
    //   width: 150,
    //   align: "center",
    //   template: (obj: TaskItem) => {
    //     //动态处理
    //     return `${obj.progress * 100}%`
    //   },
    // },
    // {
    //   name: "type",
    //   label: "类型",
    //   width: 150,
    //   align: "center",
    //   template: (obj: TaskItem) => {
    //     //动态处理
    //     return `${obj.progress * 100}%`
    //   },
    // },
    // {
    //   name: "start_date",
    //   label: "开始日期",
    //   width: 100,
    //   align: "center",
    // },
    // {
    //   name: "end_date",
    //   label: "完成时间",
    //   width: 100,
    //   align: "center",
    // },
    // {
    //   name: "action", // 新增按钮
    //   label: "操作",
    //   width: 180,
    //   align: "center",
    //   template: actionColumnTemplate,
    // },
    // {
    //   name: "setColunm", //操作表格列
    //   label: "",
    //   width: 40,
    //   align: "center",
    // },
  ],

  grid_column_width: 100,

  //用户可以通过拖拽调整行高
  resize_rows: true,

  //日期格式化的匹配格式
  xml_date: "%Y-%m-%d",

  //甘特图任务悬浮框位置
  tooltip_offset_x: 10,
  tooltip_offset_y: 10,

  //激活列表展开（折叠）功能
  open_split_tasks: true,

  //界面初始化时展开图表树形结构[按钮动态控制，展示和收缩所有]
  open_tree_initially: true,

  //图表项目栏可以任意拖拽（任意节点下) [需要事件的监听处理]
  order_branch: false,
  order_branch_free: false,

  //是否显示依赖连线(取消) [按钮动态控制，展示和收缩所有]
  show_links: true,

  //连线的线条宽度
  link_line_width: 1,

  //显示进度
  show_progress: true,

  //柱子的高度
  bar_height: 15,
  autoscroll: true,

  //配置甘特图时间刻度高度
  scale_height: 40,

  //设置行高
  row_height: 35,

  //时间轴图表中，如果不设置，只有行边框，区分上下的任务，设置之后带有列的边框，整个时间轴变成格子状。
  show_task_cells: true, //false会导致timeline_cell_class不展示

  //时间列最小宽度[这里需要动态依据类型进行判断]
  min_column_width: 80,

  //开启工作日
  work_time: true,

  //允许用户通过拖拽任务的条形图的两端来改变工期
  drag_resize: true,

  //允许用户拖动条形图来改变位置
  drag_move: true,

  //禁止拖动任务进度
  drag_progress: true,

  //禁止拖放添加Link
  drag_links: false,

  //单击|双击开启默认编辑框禁用
  details_on_dblclick: false,
  details_on_click: false,

  //插件配置
  plugins: {
    marker: true, //开启marker插件
    tooltip: true, //鼠标悬浮，展示提示框
    quick_info: false, // 快速信息框
    multiselect: false, // 是否开启task任务多选
    auto_scheduling: true, //自动排程
  },
}

//设置周日期
const weekScaleTemplate = (date: Date): string => {
  const dateToStr = gantt.date.date_to_str("%d")
  const endDate = gantt.date.add(gantt.date.add(date, 1, "week"), -1, "day")
  return `${dateToStr(date)}  - ${dateToStr(endDate)}`
}

//甘特图日期配置项
const setScaleConfig = (level: string): void => {
  switch (level) {
    case "hour":
      gantt.config.scales = [
        { unit: "day", step: 1, format: "%Y/%m/%d" },
        { unit: "hour", step: 1, date: "%H" },
      ]
      break
    case "day":
      gantt.config.scales = [
        { unit: "day", step: 1, format: "%d" },
        { unit: "month", step: 1, format: "%Y/%m" },
      ]
      break
    case "week":
      gantt.config.scales = [
        { unit: "week", step: 1, format: weekScaleTemplate },
        { unit: "month", step: 1, format: "%Y/%m" },
      ]
      break
    case "month":
      gantt.config.scales = [
        { unit: "year", step: 1, format: "%Y" },
        { unit: "month", step: 1, format: "%m月" },
      ]
      break

    //季度
    case "quarter":
      gantt.config.scales = [
        { unit: "year", step: 1, format: "%Y" },
        {
          unit: "quarter",
          step: 1,
          format: function (date: Date) {
            var dateToStr = gantt.date.date_to_str("%m")
            return dateToStr(date) + "月 "
          },
        },
      ]
      break
    case "year":
      gantt.config.scales = [{ unit: "year", step: 1, format: "%Y" }]
      break
  }
}

//修改布局
const setLayoutConfig = (level: string): void => {
  switch (level) {
    case "gridAndTimeLine":
      // 布局
      //展示配置滚动条
      gantt.config.layout = {
        css: "gantt_container",
        cols: [
          {
            width: 450,
            min_width: 450,
            rows: [
              {
                view: "grid",
                scrollX: "gridScroll",
                // scrollable: true,
                scrollY: "scrollVer",
              },
              { view: "scrollbar", id: "gridScroll", group: "horizontal" },
            ],
            // gravity: 2
          },
          { resizer: true, width: 1 },
          {
            rows: [
              { view: "timeline", scrollX: "scrollHor", scrollY: "scrollVer" },
              { view: "scrollbar", id: "scrollHor", group: "horizontal" },
            ],
          },
          { view: "scrollbar", id: "scrollVer" },
        ],
      }
      gantt.resetLayout()
      gantt.render()
      break
    case "grid":
      // 布局
      gantt.config.layout = {
        css: "gantt_container",
        rows: [
          {
            cols: [
              {
                // 默认任务列表
                view: "grid",
                scrollX: "scrollHor",
                scrollY: "scrollVer",
              },
              {
                view: "scrollbar",
                id: "scrollVer",
              },
            ],
          },
          {
            view: "scrollbar",
            id: "scrollHor",
          },
        ],
      }
      gantt.resetLayout()
      gantt.render()
      break
    case "timeLine":
      // 布局
      gantt.config.layout = {
        css: "gantt_container",
        rows: [
          {
            cols: [
              {
                // 默认甘特图（时间线）
                view: "timeline",
                scrollX: "scrollHor",
                scrollY: "scrollVer",
              },
              {
                view: "scrollbar",
                id: "scrollVer",
              },
            ],
          },
          {
            view: "scrollbar",
            id: "scrollHor",
          },
        ],
      }
      gantt.resetLayout()
      gantt.render()
      break
  }
}

//日期单位改变，手动触发甘特图日期重新渲染
const onDayHandleChange = (val: string): void => {
  setScaleConfig(val)
  gantt.render()
}

//布局修改，重新渲染
const onLayoutHandleChange = (val: string): void => {
  setLayoutConfig(val)
}

//初始化甘特
const initGantt = () => {
  gantt.config.layout = gannttConfig.layout
  gantt.config.reorder_grid_columns = gannttConfig.reorder_grid_columns
  let columns = JSON.parse(JSON.stringify(props.grid.columns))

  //处理操作列和自定义表格列
  gantt.config.columns = setControlColunm(columns)
  gantt.config.multiselect = gannttConfig.multiselect
  gantt.config.xml_date = gannttConfig.xml_date
  gantt.config.scale_height = gannttConfig.scale_height
  gantt.config.tooltip_offset_x = gannttConfig.tooltip_offset_x
  gantt.config.tooltip_offset_y = gannttConfig.tooltip_offset_y
  gantt.config.open_split_tasks = gannttConfig.open_split_tasks
  gantt.config.autofit = gannttConfig.autofit
  gantt.config.readonly = gannttConfig.readonly
  gantt.config.show_grid = gannttConfig.show_grid
  gantt.config.resize_rows = gannttConfig.resize_rows
  gantt.config.open_tree_initially = gannttConfig.open_tree_initially
  gantt.config.order_branch = gannttConfig.order_branch
  gantt.config.order_branch_free = gannttConfig.order_branch_free
  gantt.config.preserve_scroll = gannttConfig.preserve_scroll
  gantt.config.round_dnd_dates = gannttConfig.round_dnd_dates
  gantt.config.show_links = gannttConfig.show_links
  gantt.config.link_line_width = gannttConfig.link_line_width
  gantt.config.show_task_cells = gannttConfig.show_task_cells
  gantt.config.show_progress = gannttConfig.show_progress
  gantt.config.sort = gannttConfig.sort
  gantt.config.row_height = gannttConfig.row_height
  gantt.config.bar_height = gannttConfig.bar_height
  gantt.config.autoscroll = gannttConfig.autoscroll
  gantt.config.work_time = gannttConfig.work_time
  gantt.config.min_column_width = gannttConfig.min_column_width
  gantt.config.drag_project = gannttConfig.drag_project
  gantt.config.details_on_dblclick = gannttConfig.details_on_dblclick
  gantt.config.show_errors = gannttConfig.show_errors
  gantt.config.details_on_click = gannttConfig.details_on_click
  gantt.config.drag_move = gannttConfig.drag_move
  gantt.config.drag_progress = gannttConfig.drag_progress
  gantt.config.drag_links = gannttConfig.drag_links
  gantt.config.drag_resize = gannttConfig.drag_resize
  gantt.i18n.setLocale(gannttConfig.lang)
  gantt.plugins(gannttConfig.plugins)

  //添加今日的 Marker Line
  gantt.addMarker({
    start_date: new Date(),
    css: "today",
    text: "今日:" + Dayjs(new Date()).format("YYYY-MM-DD"),
  })

  const { start_date, end_date } = props.projectDate

  //添加项目开始日期Marker Line
  if (start_date) {
    gantt.addMarker({
      start_date: new Date(start_date),
      css: "projectStartDate",
      text: "项目开始:" + Dayjs(new Date(start_date)).format("YYYY-MM-DD"),
    })
  }

  //添加项目结束日期Marker Line
  if (end_date) {
    gantt.addMarker({
      start_date: new Date(end_date),
      css: "projectEndDate",
      text: "项目结束:" + Dayjs(new Date(end_date)).format("YYYY-MM-DD"),
    })
  }

  //设置周末高亮
  gantt.templates.timeline_cell_class = function (item, date) {
    if (ganttInfo.curDayType === "day" || ganttInfo.curDayType === "hour") if (date.getDay() === 0 || date.getDay() === 6) return "weekend"
    return ""
  }

  //配置任务进度条内部显示元素 [(用户可自定义任务内部显示内容)]
  gantt.templates.task_text = function (start, end, task) {
    // console.log(222)
    // return `<span style="margin-left:10px;color:white;font-size:12px;">${task.text}</span>`
    return ""
  }

  //配置任务进度条内部已完成部分的文本
  gantt.templates.progress_text = function (start, end, task) {
    // return "<span style='text-align:left;10px;color:white'>" + Math.round(task.progress * 100) + "% </span>"
    return ""
  }

  //控制网格区域的样式（类名）
  gantt.templates.grid_row_class = function (start, end, task) {
    return "grid-row-class-test"
  }

  //指定分配给左侧任务栏的文本
  gantt.templates.leftside_text = function (start, end, task) {
    return `${task.duration}天`
  }

  //日期网格配置 https://docs.dhtmlx.com/gantt/desktop__table_templates.html
  // gantt.templates.date_grid = function (date, task, column) {
  //   console.log("日期网格", date, task, column)
  //   if (task && gantt.isUnscheduled(task) && gantt.config.show_unscheduled) return gantt.templates.task_unscheduled_time(task)
  //   else return gantt.templates.grid_date_format(date)
  // }

  //配置网格缩进
  gantt.templates.grid_indent = function (item) {
    return "<div class='gantt_tree_indent'></div>"
  }

  //鼠标悬浮工具提示文本配置
  gantt.templates.tooltip_text = function (start, end, task) {
    return `
      <div style='padding:2px 15px'><b style='margin-right:10px;'>任务名:</b> ${task.text}</div>
      <div style='padding:2px 15px'><b style='margin-right:10px;'>负责人:</b> ${task.person}</div>
      <div style='padding:2px 15px'><b style='margin-right:10px;'>任务进度:</b> ${task.progressText}</div>
      <div style='padding:2px 15px'><b style='margin-right:10px;'>任务状态:</b> ${task.typeText}</div>
      <div style='padding:2px 15px'><b style='margin-right:10px;'>开始时间:</b> ${gantt.templates.tooltip_date_format(start)}</div>
      <div style='padding:2px 15px'><b style='margin-right:10px;'>结束时间:</b> ${gantt.templates.tooltip_date_format(end)}</div>
      `
  }

  //任务条上的文字大小 以及取消border自带样式
  gantt.templates.task_class = function (star, end, task) {
    return "firstLevelTask"
  }

  //要设置父项的图标，请使用网格文件夹模板：
  gantt.templates.grid_folder = function (item) {
    return "<div class='gantt_folder_" + (item.$open ? "open" : "closed") + "' style='margin-right:5px'></div>"
  }

  //设置子项的图标，请使用grid_file模板 [去掉图标]
  gantt.templates.grid_file = function (item) {
    return ""
  }
  setScaleConfig(props.ganttViewDefault)
  gantt.init(ganttRef.value)
  gantt.parse({ data: ganttInfo.task, links: ganttInfo.links })
  ganttInfo.spinning = false
  bindGannttEvent()
}

//甘特图事件
const bindGannttEvent = () => {
  //双击任务
  gantt.attachEvent(
    "onTaskDblClick",
    (id: string, mode: any): boolean => {
      console.log("id", id)
      return false
    },
    {},
  )

  //https://docs.dhtmlx.com/gantt/api__gantt_drag_mode_config.html
  //进度条拖动完毕后执行
  gantt.attachEvent(
    "onAfterTaskDrag",
    function (id: string | number, mode: string, e: Event) {
      console.log(id, mode)
    },
    {},
  )
}

//处理所有子任务展示和隐藏
const setTaskSlider = () => {
  if (ganttInfo.taskSliderFlag) {
    gantt.eachTask(function (task) {
      task.$open = false
    })
  } else {
    gantt.eachTask(function (task) {
      task.$open = true
    })
  }
  ganttInfo.taskSliderFlag = !ganttInfo.taskSliderFlag
  gantt.render()
  ganttInfo.selectionTask = []
}

//导出到PDF
const exportPDF = () => {
  gantt.exportToPDF({
    name: "mygantt.pdf",
    locale: "en",
    raw: true,
  })
}

//导出到PNG
const exportPNG = () => {
  gantt.exportToPNG({
    name: "mygantt.png",
    locale: "en",
    raw: true,
  })
}

//页面全屏|非全屏切换
const onfullScreen = (): void => {
  if (screenfull.isEnabled) screenfull.toggle()
  ganttInfo.fullScreen = !ganttInfo.fullScreen
}

//控制甘特图依赖线，显示与隐藏
const setLinks = () => {
  if (!ganttInfo.showLinks) gantt.config.show_links = true
  else gantt.config.show_links = false
  ganttInfo.showLinks = !ganttInfo.showLinks
  gantt.render()
}

//新增任务
window.onGanttAddTask = (taskId: string): void => {
  console.log("onGanttAddTask")
}
//新增任务bar
const onbarAddTask = (): void => {
  console.log("onbarAddTask")
  console.log(1)
}

//修改任务bar
const onbarEditTask = (): void => {
  if (handleSelection()) {
    console.log("onbarEditTask")
    console.log(11)
  }
}

window.onGanttEditTask = (taskId: string): void => {
  console.log("onGanttEditTask")
}

//删除任务
window.onGanttRemoveTask = (taskId: string): void => {
  console.log("onGanttRemoveTask")
}

const onbarRemoveTask = (): void => {
  if (handleSelection()) {
    console.log("onbarRemoveTask")
    console.log(11)
  }
}

//执行任务
window.onGanttExecTask = (taskId: string): void => {
  console.log("onGanttExecTask")
}

const onbarExecTask = (): void => {
  if (handleSelection()) {
    console.log("onbarExecTask")
    console.log(11)
  }
}

//复选框选中任务触发
window.onGanttCheckTask = (element: HTMLInputElement, taskId: number | string) => {
  if (element.checked) {
    if (!ganttInfo.selectionTask.includes(taskId)) ganttInfo.selectionTask.push(taskId)
  } else {
    ganttInfo.selectionTask = ganttInfo.selectionTask.filter(id => taskId !== id)
  }
  console.log(ganttInfo.selectionTask)
}

//判断选择任务的个数处理
const handleSelection = (): boolean => {
  if (ganttInfo.selectionTask.length == 0) {
    message.warn("请选择要操作的数据")
    return false
  }

  if (ganttInfo.selectionTask.length > 1) {
    message.warn("请选择一条任务数据进行操作")
    return false
  }
  return true
}

// 控制操作列
const setControlColunm = (columns: any) => {
  gantt.config.columns = []
  if (props.grid.showCheckColumn) columns.unshift({ name: "buttons", label: "选择", width: 60, template: checkboxColumnTemplate, align: "center" })

  if (props.grid.showActionColumn) {
    columns.push({
      name: "action", // 新增按钮
      label: "操作",
      width: 180,
      align: "center",
      template: actionColumnTemplate,
    })
  }
  if (props.grid.showSetColumn) {
    columns.push({
      name: "setColunm", //操作表格列
      label: "",
      width: 40,
      align: "center",
    })
  }
  //添加表格序号列
  columns.unshift({
    name: "wbs",
    label: "序号",
    width: 60,
    align: "center",
    template: gantt.getWBSCode,
  })

  return columns
}
//甘特图表格表头配置[动态修改表头会调用该方法]
const onSetGanttColumn = () => {
  // ajax
  ganttInfo.spinning = true
  setTimeout(() => {
    ganttInfo.spinning = false
    let newColums = [
      {
        name: "weidu", //操作表格列
        label: "维度",
        width: 100,
        align: "center",
      },
    ]
    gantt.config.columns = setControlColunm(newColums)
    gantt.render()
  }, 1000 * 2)
}

// 切换tabs
const onTabsChange = () => {
  ganttInfo.spinning = true
  setTimeout(() => {
    ganttInfo.spinning = false
  }, 1000 * 2)
}

onMounted(() => {
  // if (ganttRef.value) getGanttData()
})

//卸载删除gantt对象
onUnmounted(() => {
  //甘特图销毁
  gantt.destructor()
  gantt.clearAll()
})
</script>

<style lang="less" scoped>
.project-plan {
  height: 100%;
  padding: 10px 20px;
  // 顶部任务栏
  .component-topbar {
    height: 90px;
    .component-topbar__top {
      height: 50px;
      .component-topbar__top-right {
        text-align: right;
        :deep(.ant-btn:not(:last-child)) {
          margin-right: 15px;
        }
      }
    }
    .component-topbar__bottom {
      height: 40px;
      :deep(.ant-btn:not(:last-child)) {
        margin-right: 10px;
      }
    }
  }

  // 甘特图主体区域
  .dhtmlx-gantt-view {
    position: relative;
    height: calc(100% - 90px);
    .ganntt-bar-view {
      position: absolute;
      right: 10px;
      top: 46px;
      z-index: 999;
    }
    .set-colunm-view {
      position: absolute;
      left: 410px;
      top: 1px;
      z-index: 999;
      cursor: pointer;
      width: 40px;
      height: 38px;
      background-color: #fafafa;
      text-align: center;
      line-height: 40px;
    }
    //甘特图主体区域
    .dhtmlx-gantt-view-layout {
      :deep(.gantt_layout_root) {
        .gantt_task_grid_row_resize {
          display: none;
        }
        .gantt_ver_scroll {
          &::-webkit-scrollbar {
            width: @webkit-scrollbar-min-width;
            height: @webkit-scrollbar-min-height;
          }
          &::-webkit-scrollbar-thumb {
            background-color: @webkit-scrollbar-thumb-modal;
          }
        }
        .action-item {
          margin: 0 7px;
          color: #1890ff;
          cursor: pointer;
        }
        .gantt_layout_cell:first-child {
          position: relative;
          box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
          &.gantt_layout_cell_border_right {
            border-right: none;
          }
        }
        //整个甘特图边框
        &.gantt_layout_cell_border_bottom {
          border-bottom: 1px solid #f0f0f0;
        }
        &.gantt_layout_cell_border_top {
          border-top: 1px solid #f0f0f0;
        }
        &.gantt_layout_cell_border_right {
          border-right: 1px solid #f0f0f0;
        }
        &.gantt_layout_cell_border_left {
          border-left: 1px solid #f0f0f0;
        }
        //周末高亮
        .weekend {
          background: #f4f7f4;
        }

        //需要注意 ⚠️：除了今日标示线已经有默认样式以外，新增加的标示线需要指定css类名来增加样式
        .projectStartDate,
        .projectEndDate {
          background: #00bcd4;
        }

        //文字超过部分点点点...
        .gantt_tree_content {
          overflow: hidden;
          text-overflow: ellipsis;
        }
        .gantt_hor_scroll {
          &::-webkit-scrollbar {
            width: @webkit-scrollbar-min-width;
            height: @webkit-scrollbar-min-height;
          }
          &::-webkit-scrollbar-thumb {
            background-color: @webkit-scrollbar-thumb-modal;
          }
        }
        //gantt 边框样式调整

        .gantt_layout_cell_border_right.gantt_resizer {
          border-right: 0 !important;
        }

        .gantt_grid_scale,
        .gantt_task_scale {
          background-color: #fafafa;
          border-bottom: 1px solid #f0f0f0;
        }
        .gantt_scale_line {
          border: none;
          border-top: 1px solid #f0f0f0;
          background-color: #fafafa;
        }

        .gantt_grid_data .gantt_last_cell,
        .gantt_grid_scale .gantt_last_cell,
        .gantt_task .gantt_task_scale .gantt_scale_cell.gantt_last_cell,
        .gantt_task_bg .gantt_last_cell {
          border-right-width: 0 !important;
        }

        // 选中 & 鼠标移入样式
        .gantt_task_row.gantt_selected {
          background: rgba(191, 28, 45, 0.08);
        }
        .gantt_grid_data .gantt_row.gantt_selected {
          background: rgba(191, 28, 45, 0.08);
        }
        .gantt_grid_data .gantt_row.odd.gantt_selected {
          background: rgba(191, 28, 45, 0.08);
        }

        //更换 open & close 图标
        .gantt_tree_icon.gantt_open {
          background-image: url() !important;
          width: 12px;
          height: 100%;
          background-size: contain;
          background-position: 50%;
          margin-right: 0.3rem;
        }

        .gantt_tree_icon.gantt_close {
          background-image: url() !important;
          width: 12px;
          height: 100%;
          background-size: contain;
          background-position: 50%;
          margin-right: 0.3rem;
        }

        .firstLevelTask {
          border: none;
        }

        /** 进度条样式 */
        .gantt_slider {
          width: 530px;
          height: 20px;
          margin-left: 10px;
          display: inline-block;
        }

        .gantt_slider input {
          width: 34px;
          height: 18px;
          border: none;
        }

        .gantt_slider div:first-child,
        .gantt_slider .gantt_slider_value {
          display: inline-block;
          vertical-align: middle;
          line-height: 13px;
        }

        .gantt_slider .gantt_slider_value {
          font-size: 15px;
          color: black;
          margin: 5px 10px;
        }

        //去掉甘特图图表右边框
        .gantt_task_cell {
          border-right: none;
          &.week_end {
            background-color: #e5e2e2;
          }
        }

        .gantt_task_row.gantt_selected .gantt_task_cell.week_end {
          background-color: #e5e2e2;
        }

        .gantt_task_row.gantt_selected .gantt_task_cell.week_end {
          background-color: #e5e2e2;
        }
        .gantt_row,
        .gantt_task_row {
          border-bottom: 1px solid #f0f0f0;
        }

        /* 表格表头 */
        .gantt_grid_head_cell {
          color: #000000d9;
          font-weight: 500;
          border-right: 1px solid #f0f0f0 !important;
        }

        /* 日期表头 */
        .gantt_scale_cell {
          color: #000000d9;
          font-weight: 500;
        }

        /* 日期表头列icon水平居中 */
        .gantt_sort {
          top: 15px !important;
        }
      }
    }
  }
}

//spin组件高度塌陷问题
:deep(.ant-spin-nested-loading) {
  height: 100%;
  .ant-spin-container {
    height: 100% !important;
  }
}

:deep(.ant-tabs-nav-wrap) {
  background-color: #fff;
}
</style>
